package com.stox.client.ui.javafx.workbench.view;

import java.util.HashSet;
import java.util.Set;

import javafx.event.EventHandler;
import javafx.geometry.Rectangle2D;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;

import com.stox.client.ui.core.model.intf.Configurable;
import com.stox.client.ui.javafx.core.util.CSS;
import com.stox.client.ui.javafx.core.util.UI;
import com.stox.client.ui.javafx.workbench.stage.StoxStage;
import com.stox.shared.core.model.intf.Callback;
import com.stox.shared.core.util.StringUtil;

public abstract class View extends BorderPane implements Configurable {

	private EventHandler<MouseEvent> toFrontEventHandler = new EventHandler<MouseEvent>(){
		@Override
		public void handle(MouseEvent event) {
			select();
		}
	}; 
	
	private TitleBar titleBar = new TitleBar(this);
	private boolean maximized = false;
	private Rectangle2D backupWindowBounds = null;
	private final Set<Callback<Void,Void>> onOpenCallbacks = new HashSet<>();
	private final Set<Callback<Void,Void>> onCloseCallbacks = new HashSet<>();
	private ViewResizeRelocateMouseEventHandler viewResizeRelocateMouseEventHandler 
	= new ViewResizeRelocateMouseEventHandler();
	
	public View(String titleText) {
		UI.style(this, CSS.view);
		
		setTop(titleBar);
		if(StringUtil.hasText(titleText)){
			titleBar.setTitleText(titleText);
		}
		
		viewResizeRelocateMouseEventHandler.applyStageResizeRelocateMouseEventHandler(this);
		titleBar.addEventFilter(MouseEvent.MOUSE_PRESSED, toFrontEventHandler);
		addEventFilter(MouseEvent.MOUSE_PRESSED, toFrontEventHandler);
		
		select();
	}
	
	public void configure(){
		// Empty implementation, override only if needed
	}
	
	public void select(){
		toFront();
		requestFocus();
	}
	
	public void open(){
		for(Callback<Void,Void> callback : onOpenCallbacks){
			callback.execute(null);
		}
		setVisible(true);
		StoxStage stoxStage = StoxStage.INSTANCE;
		if(!stoxStage.getContentPane().getChildren().contains(this)){
			final double minHeight = getMinHeight();
			final double minWidth = getMinWidth();
			final double maxHeight = getMaxHeight();
			final double maxWidth = getMaxWidth();
			
			setMinHeight(getPrefHeight());
			setMinWidth(getPrefWidth());
			setMaxHeight(getPrefHeight());
			setMaxWidth(getPrefWidth());
			
			stoxStage.getContentPane().getChildren().add(this);
			autosize();
			
			setMinHeight(minHeight);
			setMinWidth(minWidth);
			setMaxHeight(maxHeight);
			setMaxWidth(maxWidth);
		}
	}
	
	public void close(){
		for(Callback<Void,Void> callback : onCloseCallbacks){
			callback.execute(null);
		}
		StoxStage.INSTANCE.getContentPane().getChildren().remove(this);
		setVisible(false);
	}
	
	public TitleBar getTitleBar() {
		return titleBar;
	}
	
	public boolean isMaximized() {
		return maximized;
	}
	
	public void setMaximized(boolean maximized) {
		this.maximized = maximized;
	}
	
	public Rectangle2D getBackupWindowBounds() {
		return backupWindowBounds;
	}
	
	public void setBackupWindowBounds(Rectangle2D backupWindowBounds) {
		this.backupWindowBounds = backupWindowBounds;
	}

	public ViewResizeRelocateMouseEventHandler getViewResizeRelocateMouseEventHandler() {
		return viewResizeRelocateMouseEventHandler;
	}
	
	public void addOnOpenCallback(Callback<Void,Void> callback){
		onOpenCallbacks.add(callback);
	}
	
	public void addOnCloseCallback(Callback<Void,Void> callback){
		onCloseCallbacks.add(callback);
	}
}
